package com.giCompiler.business;

import java.sql.Date;
import java.util.ArrayList;
import java.util.List;

import org.hibernate.Session;

import com.giCompiler.bean.CodigoFonte;
import com.giCompiler.bean.Pacote;
import com.giCompiler.bean.Projeto;
import com.giCompiler.dao.CodigoFonteDao;
import com.giCompiler.dao.PacoteDao;
import com.giCompiler.exception.BusinessException;
import com.giCompiler.util.HibernateUtil;

public class CriarClasseBusiness {
	
	public void criarClasseBusiness(int idPacote, Projeto projeto, int idUsuario, String nomeClasse)throws BusinessException{ 
		
		if(idPacote > 0){
	
			if(verificarDisponibilidadeNomeClasse(nomeClasse, idPacote, projeto.getIdProjeto()) == true){
				
				CodigoFonte cf = new CodigoFonte();
				
				cf = montarCodigoFonteDefault(projeto, idPacote, idUsuario, nomeClasse);
				new CodigoFonteDao().inserir(cf);
			
			}else{
				System.out.println("Ja existe um classe com o nome escolhido!");
				throw new BusinessException("Ja existe um classe com o nome escolhido!");
			}
			
		}else{
		
			if(!verificarSeTemPacDefault(projeto.getIdProjeto()))
				idPacote = criarPacoteDefault(0, projeto, "default");
			else
				idPacote = pegarIdPacoteDefault(projeto.getIdProjeto());
			
			CodigoFonte cf = new CodigoFonte();
			
			cf = montarCodigoFonteDefault(projeto, idPacote, idUsuario, nomeClasse);
			new CodigoFonteDao().inserir(cf);
			
		}		
	}
	
	//Verifica disponibilidade do nome da classe
	public boolean verificarDisponibilidadeNomeClasse(String nomeClasse, int idPacote, int idProjeto){
		
		List<CodigoFonte> cfs = new ArrayList <CodigoFonte> ();		
		CodigoFonteDao codigoFonteDao = new CodigoFonteDao();
		
		cfs = codigoFonteDao.verificarDisponibilidadeNomeClasse(nomeClasse, idPacote, idProjeto);
		
		if(cfs.isEmpty())
			return true; /*Disponivel*/
		else
			return false; /*Não disponivel*/		
		
	}

	public CodigoFonte montarCodigoFonteDefault(Projeto projeto, int idPacote, int idUsuario, String nome){
		
		String codigoFonteDefault = "";
		String caminhoDetalhado = "";
		
		caminhoDetalhado = montarCaminhoDetalhado(idPacote, projeto.getIdProjeto());
			
		if(caminhoDetalhado != null)
			
			codigoFonteDefault = "package "+caminhoDetalhado+";"+
					             "\n\npublic class "+nome+"{"+
								 "\n\n}";
			
		else
			codigoFonteDefault = "public class "+nome+"{"+
								 "\n\n}";

		CodigoFonte codigoFonte = new CodigoFonte();
		
		codigoFonte.setIdCodigoFonte(-1);
		codigoFonte.setIdPacote(idPacote);
		codigoFonte.setCodigoFonte(codigoFonteDefault);
		codigoFonte.setIdUsuario(idUsuario);
		codigoFonte.setDataCriacao(pegarDataAtual());
		codigoFonte.setDataModificacao(pegarDataAtual());
		codigoFonte.setNome(nome);
		
		return codigoFonte; 
		
	}
	
	//Monta caminho detalhado do pacote da classe
	public String montarCaminhoDetalhado(int idPacote, int idProjeto){
		
		String caminhoDetalhado = "";
		List<String> listaNomePacotes = new ArrayList<String>();
		
		Session session = HibernateUtil.getSessionFactory().openSession();
		
		pegarPacotesParaCD(idPacote, idProjeto, listaNomePacotes, session);
		
		session.close();
		
		for(int i=listaNomePacotes.size()-1; i>=0; --i){
			if(i != 0)
				caminhoDetalhado += listaNomePacotes.get(i)+".";
			else
				caminhoDetalhado += listaNomePacotes.get(i);
		
		}
	
		if(listaNomePacotes.size() == 1)
			if(listaNomePacotes.get(0).equals("default"))
				return null;
		
		return caminhoDetalhado;
		
	}
	
	//Busca os pacotes para a construcao do caminho detalhado
	public void pegarPacotesParaCD(int idPacote, int idProjeto, List<String> listaNomePacotes, Session session){
				
		PacoteDao pacoteDao = new PacoteDao();
		Pacote pacote = new Pacote(); 	
						
		pacote = pacoteDao.buscarPacotesParaCD(idPacote, idProjeto, session);
		
		if(pacote != null){
			listaNomePacotes.add(pacote.getNome());
			pegarPacotesParaCD(pacote.getIdPacSup(), idProjeto, listaNomePacotes, session);		    
		}	
	}
	
	public boolean verificarSeTemPacDefault(int idProjeto){
		
		List<Pacote> pacotes = new ArrayList<Pacote>();
		PacoteDao pacoteDao = new PacoteDao();	
		
		pacotes = pacoteDao.pegarPacoteDefault(idProjeto);
		
		if(pacotes.size() == 0)
			return false;
		else
			return true;	
		
	}
	
	public int criarPacoteDefault(int idPacSup, Projeto projeto ,String nomePacote)throws BusinessException{

		Pacote pacote = new Pacote();
	
		pacote.setIdPacote(-1);
		pacote.setIdPacSup(0);
		pacote.setIdProjeto(projeto.getIdProjeto());
		pacote.setNome(nomePacote);
		pacote.setDataCriacao(pegarDataAtual());			
		
		new PacoteDao().inserir(pacote);		
		
		return pacote.getIdPacote();
	}
		
	public int pegarIdPacoteDefault(int idProjeto){
		
		List<Pacote> pacotes = new ArrayList<Pacote>();
		PacoteDao pacoteDao = new PacoteDao();
		
		pacotes = pacoteDao.pegarPacoteDefault(idProjeto);
		
		if(pacotes.size() != 0)
			return pacotes.get(0).getIdPacote();
		else 
			return -1;
		
	}	
		
	public Date pegarDataAtual(){
		
		return new Date(System.currentTimeMillis());
		
	}
}
